package com.yuxi.Dao.Impl;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.transform.Transformers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate4.HibernateCallback;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.remoting.caucho.HessianProxyFactoryBean;
import org.springframework.stereotype.Repository;


import com.yuxi.Dao.BaseDao;
import com.yuxi.Request.Page;
import com.yuxi.Response.Obj;

public class BaseDaoImpl<T extends Serializable, PK extends Serializable>
implements BaseDao<T, PK> {
	@Autowired
	private HibernateTemplate  hibernateTemplate;
	private Class<? extends Serializable> entityClass;
	
	 public BaseDaoImpl(Class<? extends Serializable> entityClass) {
	    	this.entityClass = entityClass;
	    	
	 }
	
		public BaseDaoImpl() {
		super();
	}

		@SuppressWarnings("unchecked")
		public T get(PK id) {			
	    	return (T) hibernateTemplate.get(entityClass,id);
	    }
		
	    public void flush() {
	    	hibernateTemplate.flush();
	    }
		@Override
		public Serializable add(PK id) {
			 return hibernateTemplate.save(id);
		}
		@Override
		public void delete(PK id) {
			 hibernateTemplate.delete(id);
		}
		@Override
		public void update(PK id) {
			 hibernateTemplate.update(id);
		}
		@Override
		public List find(String hql) {
			
			return hibernateTemplate.find(hql);			
		}
		@Override
		public List find(String hql, PK... attr) {
			return  hibernateTemplate.find(hql,attr);			
		}
		@Override
		public T addAndReturn(PK id) {
			return (T)hibernateTemplate.get(entityClass, this.add(id));
			
		}


		@Override
		public Page splitPageQuery(String hql, Page p, PK... attr) {
			hibernateTemplate.execute(new HibernateCallback<T>() {
				@Override
				public T doInHibernate(Session session) throws HibernateException {
					Query query = session.createQuery(hql);
				
					for(int i=0;i<attr.length;i++)
					{
						query.setParameter(i, attr[i]);
					}
			        query.setFirstResult((p.getCurrentPage()-1)*p.getPageSize());
			        query.setMaxResults(p.getPageSize());
			        p.setList(query.list());
			        if(p.getTotalRow()==0)
			        {	String phql="select count(*) "+hql;
						Query querycount = session.createQuery(phql);
						for(int i=0;i<attr.length;i++)
						{
							querycount.setParameter(i, attr[i]);
						}
					Serializable a=(Serializable) querycount.uniqueResult();	
						p.setTotalRow(Integer.parseInt(a.toString()));
			        }			     
					return null;
				}
			});
			return p;
		}

		@Override
		public void delete(String hql,PK ...attr) {
			// TODO Auto-generated method stub
			hibernateTemplate.bulkUpdate(hql, attr);
			
		}

		@Override
		public Page splitPageQuerySlect(String hql, Page p,String noSelct,PK... attr) {
			hibernateTemplate.execute(new HibernateCallback<T>() {
				@Override
				public T doInHibernate(Session session) throws HibernateException {
				
					Query query = session.createQuery(hql);
				
					for(int i=0;i<attr.length;i++)
					{	
						query.setParameter(i, attr[i]);
					}					
			        query.setFirstResult((p.getCurrentPage()-1)*p.getPageSize());
			        query.setMaxResults(p.getPageSize());			     
			        p.setList(query.list());
			        if(p.getTotalRow()==0)
			        {	String phql="select  count(*) "+noSelct;
						Query querycount = session.createQuery(phql);
						
						for(int i=0;i<attr.length;i++)
						{
							querycount.setParameter(i, attr[i]);
						}
					Serializable a=(Serializable) querycount.uniqueResult();	
						p.setTotalRow(Integer.parseInt(a.toString()));
			        }			        
					return null;
				}
			});
			return p;
		}
		@Override
		public Page splitPageQuerySelect(String hql, Page p,String noSelct,PK... attr) {
			hibernateTemplate.execute(new HibernateCallback<T>() {
				@Override
				public T doInHibernate(Session session) throws HibernateException {
				
					Query query = session.createQuery(hql);
				
					for(int i=0;i<attr.length;i++)
					{	
						query.setParameter(i, attr[i]);
					}					
					
			        query.setFirstResult((p.getCurrentPage()-1)*p.getPageSize());
			        query.setMaxResults(p.getPageSize());			     
			        p.setList(query.list());
			        if(p.getTotalRow()==0)
			        {	String phql="select  count(distinct "+noSelct;
			        System.out.println(phql);
						Query querycount = session.createQuery(phql);
						
						for(int i=0;i<attr.length;i++)
						{
							querycount.setParameter(i, attr[i]);
						}
					Serializable a=(Serializable) querycount.uniqueResult();	
						p.setTotalRow(Integer.parseInt(a.toString()));
			        }			        
					return null;
				}
			});
			return p;
		}
	@Override	
	public Integer execute(String sql,Object... arges){		
		return (Integer)hibernateTemplate.execute(new HibernateCallback<Integer>() {
			@Override
			public Integer doInHibernate(Session session) throws HibernateException {
				//System.out.println(sql);
				SQLQuery  query=session.createSQLQuery(sql);
				for(int i=0;i<arges.length;i++)
				{
					query.setParameter(i, arges[i]);
				}
				Serializable a=(Serializable)query.uniqueResult();	
				Integer i=Integer.parseInt(a.toString());				
				return i ;
			}			
		});
	}

	@Override
	public List<Map<String, Object>> executeSql(String sql, Object... arges) {
		return (List<Map<String, Object>>)hibernateTemplate.execute(new HibernateCallback<List<Map<String, Object>>>() {
			@Override
			public List<Map<String, Object>> doInHibernate(Session session) throws HibernateException {
			
				Query   query=session.createSQLQuery(sql);				
				for(int i=0;i<arges.length;i++)
				{
					query.setParameter(i, arges[i]);
				}
				
				return (List) query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
			}			
		});
	}
	
}
